package bert;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

public class PolyFitter {

    public static Collection<Polygon> apply(Collection<Polygon> ps, int epsilon) {
        ArrayList<Polygon> result = new ArrayList<Polygon>();

        for (Polygon p0 : ps) {
            ArrayList<Polygon> neighbours = findNeighbours(p0, ps, epsilon);
            ArrayList<Vec2> neighbourVertices = getNeighbourVertices(neighbours);

            ArrayList<Vec2> newVertices = new ArrayList<Vec2>();

            for (Vec2 v0 : p0.GetVertices()) {
                int x = v0.X;
                int y = v0.Y;

                int count = 1;

                for (Vec2 v : neighbourVertices) {
                    if (v.distance(v0) <= epsilon) {
                        x += v.X;
                        y += v.Y;
                        ++count;
                    }
                }

                newVertices.add(new Vec2(x / count, y / count));
            }

            result.add(new Polygon(newVertices.toArray(new Vec2[newVertices.size()]), p0.Id));
        }

        return Collections.unmodifiableCollection(result);
    }

    private static ArrayList<Vec2> getNeighbourVertices(ArrayList<Polygon> neighbours) {
        ArrayList<Vec2> result = new ArrayList<Vec2>();

        for (Polygon neighbour : neighbours) {
            for (Vec2 p : neighbour.GetVertices()) {
                result.add(p);
            }
        }

        return result;
    }

    private static ArrayList<Polygon> findNeighbours(Polygon p0, Collection<Polygon> ps, int epsilon) {
        ArrayList<Polygon> result = new ArrayList<Polygon>();

        for (Polygon p : ps) {
            if (p != p0 && p.aabb.expanded(epsilon * 3).intersects(p0.aabb)) {
                result.add(p);
            }
        }

        return result;
    }
}
